/*
 *  @Title AbstractTreeOperate.java
 *  @Package： com.phoenix.core.tree
 *  Copyright (c) 2017 by 江苏深南互联网金融信息服务有限公司  All right reserved
 */
package com.phoenix.core.tree;

import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

/**
 *  @ClassName AbstractTreeOperate
 *  @Description 树抽象操作类查询数据生成内存树实现自己的树必须实现树数据查找方法及初始化方法
 *  @author liuwenbin
 *  @version 1.0
 *  @date 2017年7月5日
 */
public abstract class AbstractTreeOperate {

	// 节点记录map
	protected Map<String, String> keyMap = new HashMap<String, String>();

	// 从数据库查询的数据,为便于查找用的map,为了遍历速度用的LinkedHashMap
	protected Map<String, TreeNode> treeMp = null;

	// 虚拟根节点
	protected JcTreeNode root = null;

	// 堆栈
	protected JcStack<TreeNode> stack = null;

	// 全局节点变量
	protected JcTreeNode addNode = null;

	// 接口及DAO初始化
	protected abstract void init();

	private int count = 0;// 避免组织结构错误死循环down机

	/**
	 * 从数据库查询树,并转化为页面表现格式
	 */
	public abstract String getTreeData(String condition);

	synchronized protected void constructTree() {
		root = new JcTreeNode();// 新增一个虚拟根节点
		root.setRoot();// 将节点设置为根节点
		changeNode();// 转化数据库数据为内存树
	}

	/** 树节点的拖动 */
	public boolean moveTree(String nodeId, String parentId, String dtype) {
		return false;
	}

	protected void clear() {
		if (this.keyMap != null) {
			this.keyMap.clear();
		}
		if (this.treeMp != null) {
			this.treeMp.clear();
		}
		this.root = null;
		this.stack = null;
		this.addNode = null;
		this.count = 0;
	}

	/** 将数据库树数据转化为内存树 */
	protected void changeNode() {
		TreeNode branchNode = null;
		Iterator<String> it = treeMp.keySet().iterator();
		while (it.hasNext()) {
			String key = it.next();
			branchNode = treeMp.get(key);
			if (keyMap.containsKey(key)) {
				continue;
			}
			if (branchNode == null)
				continue;
			if (!isIterator(branchNode)) {
				count = 0;
				stack = new JcStack<TreeNode>();
				isFound(branchNode);
				while (stack.isEmpty() == false) {
					TreeNode itnode = stack.pop();
					isIterator(itnode);
				}
			}
		}
	}

	protected void isFound(TreeNode child) {
		count++;
		if ((child.getParentId()).equals(root.getId())) {
			keyMap.put(child.getId(), null);
			root.addNode(child);
		} else {
			if (!isIterator(child)) {
				stack.push(child);
				addNode = (JcTreeNode) treeMp.get(child.getParentId());
				if (addNode != null) {
					if (count < 1000) {
						isFound(addNode);
					}
				}
			}
		}
	}

	/** 树数据遍历 */
	private boolean isIterator(TreeNode child) {
		// 采用的是深度遍历,可根据需要换为广度遍历
		for (Iterator<TreeNode> itsub = new DepthIterator(root.iterator()); itsub.hasNext();) {
			TreeNode childone = itsub.next();
			if (childone == null)
				return Boolean.FALSE;
			if (child.getParentId().equals(childone.getId())) {
				keyMap.put(child.getId(), null);
				childone.addNode(child);
				return Boolean.TRUE;
			}
		}
		return Boolean.FALSE;
	}
}
